package com.midea.freecolder;


import java.util.concurrent.*;

public class ThreadPoolDemo {
    public static void main(String[] args) throws InterruptedException {
        ExecutorService e1 = Executors.newCachedThreadPool();
        /**
         * new SynchronousQueue<Runnable>()，同步队列，大小为0
         * 可能存在问题：
         * 60s合不合理？
         * maximumPoolSize = Integer.MAX_VALUE合不合理？创建这么多线程会不会OOM？
         * */
        for (int i=0;i<100;i++){
            e1.execute(new MyTask(i));
        }
        Thread.sleep(70 * 1000);
        for (int i=100;i<200;i++){
            e1.execute(new MyTask(i));
        }
        ExecutorService e2 = Executors.newFixedThreadPool(10);
        /**
         * new LinkedBlockingQueue<Runnable>()，无穷大队列
         * 核心线程不会回收，超时时间只对救命线程（非核心线程）有效
         * 可能存在问题：
         * 队列长度无穷大，合不合理？一直塞任务会不会内存爆掉OOM？
         * */
        for (int i=0;i<100;i++){
            e2.execute(new MyTask(i));
        }
        Thread.sleep(12 * 1000);
        for (int i=100;i<200;i++){
            e2.execute(new MyTask(i));
        }
        ExecutorService e3 = Executors.newSingleThreadExecutor();

        //创建一个按照计划规定执行的线程池，这里核心数 = 2
        ExecutorService e4 = Executors.newScheduledThreadPool(2);
        //工作窃取线程池， 用到了分而治之，递归计算的算法
        ExecutorService e5 = Executors.newWorkStealingPool();
        /**
         * corePoolSize,核心线程数量
         * maximumPoolSize,最大线程数量
         * keepAliveTime,无任务时存活时间
         * unit,keepAliveTime的时间单元
         * workQueue,任务阻塞队列
         * maximumPoolSize = corePoolSize（核心线程数量）+ 非核心线程
         * 任务来时，先由核心线程去执行任务，当任务数量>corePoolSize时，多余任务会放在workQueue队列里等待执行，
         * 当任务数量>corePoolSize+workQueue时，线程池会创建非核心线程来执行任务
         * 当任务量>maximumPoolSize+workQueue时，报拒绝执行异常java.util.concurrent.RejectedExecutionException
         * */
        ThreadPoolExecutor t = new ThreadPoolExecutor(10,20,10,
                TimeUnit.SECONDS,new ArrayBlockingQueue<>(10));
        /**
         *
         * 拒绝策略：当线程池的任务缓存队列已满并且线程池中的线程数目达到maximumPoolSize时，如果还有任务到来就会采取任务拒绝策略，通常有以下四种策略：
         *ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。 T
         *ThreadPoolExecutor.DiscardPolicy：丢弃任务，但是不抛出异常。
         *ThreadPoolExecutor.DiscardOldestPolicy：丢弃队列最前面的任务，然后重新提交被拒绝的任
         *ThreadPoolExecutor.CallerRunsPolicy：由调用线程（提交任务的线程）处理该任务
         */
        t.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
        //t.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());
        //t.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardOldestPolicy());
        //t.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        for (int i=0;i<100;i++){
            t.execute(new MyTask(i));
        }
    }
}

class MyTask implements Runnable{
    int i;
    public MyTask(int i){
        this.i = i;
    }

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+"-----"+i);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
